package com.springmvc.servlet;

import com.springmvc.anotation.RequestMapping;
import com.springmvc.context.WebApplicationContext;
import com.springmvc.handler.MyHandler;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class DispatchServlet extends HttpServlet {

    private WebApplicationContext webApplicationContext;
    private List<MyHandler> handlers = new ArrayList<>();

    @Override
    public void init() throws ServletException {
        String contextConfigLocation = this.getServletConfig().getInitParameter("contextConfigLocation");
        webApplicationContext = new WebApplicationContext(contextConfigLocation);
        webApplicationContext.refresh();
        initHandlerMapping();
        System.out.println("请求地址" + handlers);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        excuteDispatch(req, resp);
    }

    private void excuteDispatch(HttpServletRequest req, HttpServletResponse resp) {
        MyHandler handler = getHandler(req);
        if (handler == null) {
            try {
                resp.getWriter().print("<h1>401 Not Found</h1>");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Class<?>[] parameterTypes = handler.getMethod().getParameterTypes();
        Object[] params = new Object[parameterTypes.length];
        Map<String, String[]> parameterMap = req.getParameterMap();
//        for (String[] value : parameterMap.values()) {
//
//        }
        // TODO 后期动态处理
        params[0] = req;
        params[1] = resp;
        params[2] = parameterMap.get("name")[0];
        try {
            handler.getMethod().invoke(handler.getController(), params);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private MyHandler getHandler(HttpServletRequest req) {
        System.out.println(req.getRequestURL());
        System.out.println(req.getRequestURI());
        String requestURI = req.getRequestURI();
        for (MyHandler handler : handlers) {
            if (handler.getUrl().equals(requestURI)) {
                return handler;
            }
        }
        return null;
    }

    private void initHandlerMapping() {
        //
//        new MyHandler(url, )
        for (Object obj : webApplicationContext.getBeanMap().values()) {
            Class<?> clazz = obj.getClass();
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                    String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                    handlers.add(new MyHandler(url, obj, declaredMethod));
                }
            }
        }
    }


}
